<script setup lang="ts">
import { reactive, ref, watch, computed } from 'vue'
import { ElMessage, type FormRules } from 'element-plus'
import { hasSpaceWithStartAndEnd } from '@/utils/validate'
import { uploadFile } from '@/utils/uploader'
import { useFileDialog } from '@vueuse/core'
import ImageUploader from '@/plugins/stratocirri-plus/components/image-uploader/ImageUploader.vue'
import useEditorTool from '@/plugins/stratocirri-plus/hooks/useEditorTool'

interface Props {
  data?: Record<string, any> | never | null
  status?: any
}

const props = withDefaults(defineProps<Props>(), {
  data: null,
  status: 'add'
})

const emit = defineEmits<{
  (e: 'audio-play'): void
}>()

const { formatImage } = useEditorTool()

const disabled = computed(() => {
  return props.status === 'read'
})

const formRef = ref()

const form = reactive<Record<string, any>>({
  // audioUrl: props.data?.audioUrl || ''
})

const rules = reactive<FormRules>({
  showRoomName: [
    { required: true, message: '展厅名称不能为空!', trigger: 'blur' },
    {
      validator: (rule: any, value: any, callback: any) => {
        if (value) {
          if (hasSpaceWithStartAndEnd(value)) {
            callback(new Error('展厅名称首尾不能有空格!'))
          } else {
            callback()
          }
        } else {
          callback()
        }
      },
      trigger: 'blur'
    }
  ],
  otherName: [
    { required: true, message: '展厅别名不能为空!', trigger: 'blur' },
    {
      validator: (rule: any, value: any, callback: any) => {
        if (value) {
          if (hasSpaceWithStartAndEnd(value)) {
            callback(new Error('展厅别名首尾不能有空格!'))
          } else {
            callback()
          }
        } else {
          callback()
        }
      },
      trigger: 'blur'
    }
  ],
  imageUrl: [{ required: true, message: '展厅图片不能为空!', trigger: 'blur' }],
  audioUrl: [{ required: true, message: '音频文件不能为空!', trigger: 'blur' }],
  content: [
    {
      required: true,
      validator: (rule, value, callback) => {
        if (!form.news || form.news === '<p><br></p>' || form.news === '<p></p>') {
          callback(new Error('文物简介不能为空!'))
        } else {
          callback()
        }
      },
      trigger: 'blur'
    }
  ]
})

const loading = ref(false)

const customEditorRef = ref()

const defaultContent = ref('[]')

const editorKey = ref(`${new Date().getTime()}`)

watch(defaultContent, () => {
  editorKey.value = `${new Date().getTime()}`
})

// const hasLoadedAudio = ref(false)
// const loadedmetadataFun = () => {
//   hasLoadedAudio.value = true
// }

const newsHtml = ref('')
const initForm = () => {
  if (props.data) {
    // 编辑
    // loading.value = true
    const res = props.data
    Object.keys(res).forEach((key: string) => {
      if (res![key] || res![key] === 0) {
        if (key === 'content') {
          defaultContent.value = res![key]
          form[key] = res![key]
        } else if (key === 'news') {
          newsHtml.value = formatImage(res[key])
        } else {
          form[key] = res![key]
        }
      }
    })
  }
}
initForm()

const handleContentChange = (content: string, html: string) => {
  form.content = content
  form.news = html
}

const formatForm = () => {
  const result: Record<string, any> = {}
  Object.keys(form).forEach((key: string) => {
    if (key === 'news') {
      result[key] = customEditorRef.value.formatImage(form[key])
    } else {
      result[key] = form[key]
    }
  })
  return result
}

const submitForm = () => {
  return new Promise<any>((resolve) => {
    formRef.value.validate((valid: boolean) => {
      let res: any = null
      if (valid) {
        res = formatForm()
      }
      resolve(res)
    })
  })
}

const { files, open, reset } = useFileDialog({
  multiple: false,
  accept: '.mp3,.wav,.aif,.midi,.ogg,.aac'
})

const callOpen = () => {
  open()
}

const removeFile = () => {
  reset()
  form.audioUrl = null
}

watch(
  files,
  (newVal) => {
    console.log(newVal)
    if (newVal) {
      // 上传
      loading.value = true
      const file = newVal[0]
      if (!form.name) {
        form.name = file.name
      }
      uploadFile({ file }, 0)
        .then((res: any) => {
          form.audioUrl = res.url
          ElMessage({
            type: 'success',
            message: '上传成功'
          })
          formRef.value.validateField(['audioUrl'])
        })
        .catch(() => {
          reset()
        })
        .finally(() => {
          loading.value = false
        })
    } else {
      // 删除
      form.audioUrl = null
    }
  },
  {
    deep: true
  }
)

const imageChange = (val: string) => {
  form.imageUrl = val
  formRef.value.validateField(['imageUrl'])
}

const handleAudioPlay = () => {
  emit('audio-play')
}

defineExpose({
  submitForm
})
</script>

<template>
  <div v-loading="loading" class="form-wrapper">
    <el-form ref="formRef" :model="form" :rules="rules" label-position="top" label-width="120px">
      <el-form-item label="展厅名称：" prop="showRoomName">
        <el-input v-model="form.showRoomName" type="text" placeholder="请输入展厅名称" maxlength="20" :disabled="disabled" />
      </el-form-item>
      <el-form-item label="展厅别名：" prop="otherName">
        <el-input v-model="form.otherName" type="text" placeholder="请输入展厅别名" maxlength="20" :disabled="disabled" />
      </el-form-item>
      <el-form-item label="展厅图片：" prop="imageUrl" class="form-item-block">
        <ImageUploader :default-url="form.imageUrl" :limit-file-size="2" @image-change="imageChange" :disabled="disabled"></ImageUploader>
      </el-form-item>
      <el-form-item label="音频文件：" prop="audioUrl">
        <div class="form-item-model-container">
          <div v-if="!form.audioUrl && !disabled" class="model-edit-text" @click="callOpen">上传音频</div>
          <div v-if="form.audioUrl && !disabled" class="model-edit-text delete" @click="removeFile">删除音频</div>
          <div v-if="form.audioUrl">
            <audio controls :src="form.audioUrl" width="330" @play="handleAudioPlay"></audio>
          </div>
        </div>
      </el-form-item>
      <el-form-item :key="editorKey" label="展厅简介：" prop="content">
        <CustomEditor v-if="!disabled" ref="customEditorRef" :default-content="defaultContent" @content-change="handleContentChange"></CustomEditor>
        <div v-if="disabled" v-dompurify-html="newsHtml" style="width: 100%; word-wrap: break-word"></div>
      </el-form-item>
    </el-form>
  </div>
</template>

<style lang="scss" scoped>
.form-wrapper {
  padding-left: 10px;
  .form-item-model-container {
    @include rect(100%, 100%);
    .model-edit-text {
      cursor: pointer;
      text-decoration: underline;
      text-underline-offset: 2px;
      color: var(--theme-color);
      &.delete {
        color: var(--theme-color-danger);
      }
    }
  }
}
</style>
